﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LX.Cache
{
    public class CacheManager
    {
        /// <summary>
        /// 缓存提供者
        /// </summary>
        private ICacheProvider _provider;

        public CacheManager()
        {
        }

        public CacheManager(ICacheProvider provider)
        {
            _provider = provider;
        }

        public void SetProvider(ICacheProvider provider)
        {
            _provider = provider;
        }

        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="value">值</param>
        /// <param name="expiresSecond">过期时间，秒</param>
        public void Set(string key, object value, int? expiresSecond=null)
        {
            if (string.IsNullOrEmpty(key))
            {
                return;
            }
            if (value==null)
            {
                return;
            }
            var cachekey = new CacheKey(key, _provider);
            if (expiresSecond == null)
            {
                _provider.Set(cachekey.GetCacheKey(), value);
            }
            else
            {
                _provider.Set(cachekey.GetCacheKey(), value, expiresSecond.Value);
            }
            if (!key.Contains("*")&&cachekey.NameSpace!=null)
            {
                RemoveList(cachekey.NameSpace);
            }
        }

        /// <summary>
        /// 获取缓存
        /// </summary>
        /// <param name="key"></param>
        /// <param name="handler"></param>
        /// <returns></returns>
        public object Get(string key,Func<object> handler=null)
        {
            if (string.IsNullOrEmpty(key))
            {
                return null;
            }
            var cachekey = new CacheKey(key, _provider);
            var result=_provider.GetData(cachekey.GetCacheKey());
            if (result != null)
            {
                return result;
            }
            if (handler != null)
            {
                result = handler();
                if (result != null)
                {
                    _provider.Set(cachekey.GetCacheKey(), result);
                    return result;
                }
                return null;
            }
            return null;
        }

        /// <summary>
        /// 移除缓存
        /// </summary>
        /// <param name="key"></param>
        public void Remove(string key)
        {
            if (string.IsNullOrEmpty(key))
            {
                return;
            }
            key = key.Trim().ToLower();
            if (key[0] != ':')
            {
                var cachekey = new CacheKey(key, _provider);
                _provider.Remove(cachekey.GetCacheKey());
                if (cachekey.NameSpace != null)
                {
                    RemoveList(cachekey.NameSpace);
                }
                return;
            }
            var keys = key.Substring(1);
            var namespacecachekey = new CacheKey(keys, _provider);
            RemoveNameSpace(namespacecachekey);
        }

        private void RemoveNameSpace(CacheKey namespacecachekey)
        {
            if (namespacecachekey == null) return;
            var key = namespacecachekey.GetCacheKey();
            _provider.Remove(key);
        }

        /// <summary>
        /// 清除列表项
        /// </summary>
        /// <param name="key"></param>
        public void RemoveList(CacheKey key)
        {
            if (key == null) return;
            var ckey = key;
            while (ckey!=null)
            {
                var listkey = ckey.FullKey + ".*";
                RemoveNameSpace(new CacheKey(listkey,_provider));
                ckey = ckey.NameSpace;
            }
        }

        /// <summary>
        /// 清除全部缓存
        /// </summary>
        public void RemoveAll()
        {
            _provider.RemoveAll();
        }
    }
}
